import requests
import re
import json
import time
import random
from urllib.parse import unquote, urlparse

def get_douyin_video(url):
    # 设置随机 User-Agent
    user_agents = [
        "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
    ]
    headers = {
        "User-Agent": random.choice(user_agents),
        "Cookie": "YOUR_COOKIE_HERE",  # 替换成实际 Cookie
        "Referer": "https://www.douyin.com/",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        "Accept": "application/json, text/plain, */*"
    }
    
    # 1. 获取重定向后的真实 URL
    session = requests.Session()
    
    try:
        resp = session.head(url, headers=headers, allow_redirects=True)
        real_url = resp.url
        print(f"视频真实地址: {real_url}")
    except Exception as e:
        print(f"获取真实地址失败: {e}")
        return None
    
    # 2. 提取视频 ID
    video_id_match = re.search(r'/video/(\d+)', real_url) or re.search(r'/share/video/(\d+)', real_url)
    if video_id_match:
        video_id = video_id_match.group(1)
        print(f"视频ID: {video_id}")
    else:
        print(f"无法提取视频ID: {real_url}")
        return None
    
    # 3. 直接调用抖音API获取视频信息
    api_url = f"https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={video_id}"
    print(f"API请求地址: {api_url}")
    
    try:
        api_response = session.get(api_url, headers=headers)
        print(f"API响应状态码: {api_response.status_code}")
        
        if api_response.status_code != 200:
            print(f"API请求失败: {api_response.text}")
            return None
            
        data = api_response.json()
        
        # 调试: 保存API响应
        with open(f"api_response_{video_id}.json", "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        print(f"已保存API响应到: api_response_{video_id}.json")
        
        # 提取视频URL
        if 'item_list' in data and len(data['item_list']) > 0:
            video_info = data['item_list'][0]['video']
            
            # 尝试获取无水印视频地址
            play_addr = video_info.get('play_addr', {})
            if play_addr:
                url_list = play_addr.get('url_list', [])
                if url_list:
                    video_url = url_list[0].replace('playwm', 'play')
                    print(f"无水印视频地址: {video_url}")
                else:
                    print("API响应中没有找到url_list")
                    return None
            else:
                print("API响应中没有play_addr")
                return None
        else:
            print("API响应中没有item_list")
            return None
    except Exception as e:
        print(f"API请求或解析失败: {e}")
        return None
    
    # 4. 下载视频
    try:
        video_headers = {
            "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1",
            "Referer": "https://www.douyin.com/",
            "Accept": "*/*",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Range": "bytes=0-",
            "Sec-Fetch-Dest": "video",
            "Sec-Fetch-Mode": "no-cors",
            "Sec-Fetch-Site": "same-site"
        }
        
        # 获取重定向后的真实视频 URL
        video_resp = session.head(video_url, headers=video_headers, allow_redirects=True)
        final_video_url = video_resp.url
        print(f"最终视频地址: {final_video_url}")
        
        # 下载视频内容
        video_response = session.get(final_video_url, headers=video_headers, stream=True)
        
        if video_response.status_code != 200:
            print(f"视频下载失败: HTTP {video_response.status_code}")
            return None
        
        # 保存文件
        filename = f"douyin_{video_id}_{int(time.time())}.mp4"
        with open(filename, "wb") as f:
            for chunk in video_response.iter_content(chunk_size=8192):
                if chunk:
                    f.write(chunk)
        
        print(f"视频已保存至: {filename}")
        return filename
    except Exception as e:
        print(f"视频下载失败: {e}")
        return None

if __name__ == "__main__":
    # 示例：抖音分享短链接
    share_url = "https://v.douyin.com/ipCFL4bBgYk/"
    get_douyin_video(share_url)